#include <iostream>
#include "stdTcpServer.h"
#include <pthread.h>
#include <unistd.h>
#include <cstring>
#include <string>
#include "threadpool.h"
#include <json-c/json.h>
#include "messageHandle.h"

#define SERVER_PORT 8080
// #define BUFFER_SIZE 64

void *handleClientFunc(void *arg)
{
    // 线程分离
    pthread_detach(pthread_self());

    StdTcpSocketPtr clientInfo = *static_cast<StdTcpSocketPtr *>(arg);
    // StdTcpSocketPtr clientInfo = *(StdTcpSocketPtr *)(arg);

    MessageHandler handle(clientInfo);

    int readBytes = 0;
    // char buffer[BUFFER_SIZE] = { 0 };
    std::string buffer;
    while (1)
    {
        // 故意制造服务器接收慢的情况
        // sleep(10);
    
        // memset(buffer, 0, sizeof(buffer));
        // readBytes = clientInfo->recvMessage(buffer, sizeof(buffer));
        readBytes = clientInfo->recvMessage(buffer);
        if (readBytes < 0)
        {
            perror("read error");
            break;
        }
        else if (readBytes == 0)
        {
            std::cout << "客户端下线" << std::endl;
            break;
        }
        else
        {
            // std::cout << "readBytes" << readBytes << ", buffer:" << buffer << std::endl;
            // std::cout << "buffer:" << buffer << std::endl;

            handle.handleMessage(buffer);
        }

        // 清空缓冲区
        buffer.clear();
    }

    // 资源回收
    close(clientInfo->getSockAttr()->connfd);
    
#if 0
    // 线程退出
    pthread_exit(NULL);
#else
    // 为什么回到线程池？
    return NULL; // 线程没退出，函数退出了
#endif
}

int main()
{
    // 启动线程池
    ThreadPool pool(2, 5, 20); // 1个核适合开4个线程


    StdTcpServer server;

    // 启动监听
    server.setListen(SERVER_PORT);

    std::cout << "等待客户端进行连接..." << std::endl;

    while (1)
    {
        // 阻塞接收客户端连接
        StdTcpSocketPtr clientInfo = server.getClientSock();
#if 0
        // 创建线程
        pthread_t tid;
        int ret = pthread_create(&tid, NULL, handleClientFunc, &clientInfo);
        if (ret != 0)
        {
            perror("thread create error");
            continue;
        }
#else
        // 放到任务队列
        pool.addTask(handleClientFunc, new StdTcpSocketPtr(clientInfo));
#endif
        sleep(1);
    }

    return 0;
}